﻿#define TRACE

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices; 


namespace EyesOnTrain
{
    public partial class MainForm : Form
    {
        private PictureBox[] _pictureBoxes = null;
        private CaptureEngine _theEngine = null;

        private int _secondInterval = 10;
        private int _secondCount = 0;

        private const int _MIN_INTERVAL = 10;   // minimum interval cannot be less than 10 seconds;
        private const int _MAX_INTERVAL = 60;   // maximum interval cannot be greater than 60 seconds;

        public MainForm()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _theEngine = CaptureEngine.Instance;
            _theEngine.NewFrameEvent += _theEngine_NewFrameEvent;

            UpdateCapDeviceListBox(_theEngine.DeviceIds);
            SetupPictureWall(_theEngine.DeviceIds);

            refreshIntervalNumericUpDown.Value = 10;
            IntervalCounter = 0;

            this.pictureWallFlowLayoutPanel.Resize += new System.EventHandler(this.pictureWallFlowLayoutPanel_Resize);

            RelayoutPictureBox();
        }

        void _theEngine_NewFrameEvent(object sender, NewFrameCapturedEventArgs e)
        {
            Trace.TraceInformation("The form get frame posted from device: " + e.DeviceId);

            if (_pictureBoxes != null)
            {
                var picBox = _pictureBoxes.FirstOrDefault(p => (string)p.Tag == e.DeviceId);
                if (picBox != null)
                    picBox.Image = (Image)e.Frame.Clone();
                else
                    Trace.TraceError("The form doesn't have corresponding picture box for device: " + e.DeviceId);
            }
        }

        private void UpdateCapDeviceListBox(string[] devicesIds)
        {
            this.capDevicesListBox.Items.Clear();

            if (devicesIds == null)
                return;

            foreach (var dev in devicesIds)
            {
                this.capDevicesListBox.Items.Add(dev);
            }
        }

        private void SetupPictureWall(string[] capDevices)
        {

            this.pictureWallFlowLayoutPanel.Controls.Clear();

            _pictureBoxes = new PictureBox[capDevices.Length];

            for (int i = 0; i < capDevices.Length; i++) 
            {
                _pictureBoxes[i] = new PictureBox();
                //_pictureBoxes[i].Width = 640;
                //_pictureBoxes[i].Height = 480;
                _pictureBoxes[i].Tag = capDevices[i];

                _pictureBoxes[i].SizeMode = PictureBoxSizeMode.StretchImage;
                _pictureBoxes[i].MouseHover += new EventHandler(MainForm_MouseHover);
                _pictureBoxes[i].BorderStyle = BorderStyle.FixedSingle;
                _pictureBoxes[i].ContextMenu = new ContextMenu();
                _pictureBoxes[i].ContextMenu.MenuItems.Add("Switch to Video Mode");
                this.pictureWallFlowLayoutPanel.Controls.Add(_pictureBoxes[i]);
            }
        }

        void MainForm_MouseHover(object sender, EventArgs e)
        {
            PictureBox pictureBox = sender as PictureBox;
            if (pictureBox == null)
                return;
        }

        private void pictureRecaptureTimer_Tick(object sender, EventArgs e)
        {
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            _theEngine.Stop();
        }

        private void pictureWallFlowLayoutPanel_Resize(object sender, EventArgs e)
        {
            RelayoutPictureBox();
        }

        private void RelayoutPictureBox()
        {
            int nPerLine = _pictureBoxes.Length < 3 ? _pictureBoxes.Length : 3;
            nPerLine = nPerLine == 0 ? 1 : nPerLine;    // avoid divided by 0

            int pictureBoxWidth = pictureWallFlowLayoutPanel.Width / nPerLine - 15;
            int pictureBoxHeight = pictureBoxWidth / 4 * 3;
            foreach (var pictureBox in _pictureBoxes)
            {
                pictureBox.Width = pictureBoxWidth;
                pictureBox.Height = pictureBoxHeight;
            }

            this.pictureWallFlowLayoutPanel.PerformLayout();
        }

        private void refreshIntervalNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            this.pictureRecaptureTimer.Stop();
            this.ResetRefreshInterval((int)this.refreshIntervalNumericUpDown.Value);
            this.pictureRecaptureTimer.Start();
        }

        private void ResetRefreshInterval(int seconds)
        {
            this._secondInterval = seconds;
            this.IntervalCounter = 0;
        }

        private int IntervalCounter
        {
            get
            {
                return this._secondCount;
            }
            set
            {
                _secondCount = value;

                UpdateRemainingText();
            }
        }

        private void UpdateRemainingText()
        {
            remainingTextLabel.Text = string.Format("Remain {0} seconds to re-capture.", _secondInterval - _secondCount);
        }

        private void MainForm_Shown(object sender, EventArgs e)
        {
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            _theEngine.Start();
        }
    }
}
